package domain;

import java.io.Serializable;
import java.util.List;
import java.util.Set;

import org.hibernate.HibernateException;
import org.springframework.dao.DataAccessException;

import util.DAOException;
import util.VersionException;
import domain.factory.POJOFactory;
import domain.itf.IDAOContactGroup;

public class DAOContactGroup extends AbstractDAO implements IDAOContactGroup {

	public DAOContactGroup() {}

	@SuppressWarnings("unchecked")
	
	public List<ContactGroup> getAllGroups() throws DAOException {
		super.getHibernateTemplate().setCacheQueries(true);
		List<ContactGroup> find = super.getHibernateTemplate().find("from ContactGroup");
		super.getHibernateTemplate().setCacheQueries(false);
		return find;
	}

	
	public ContactGroup getById(Integer id) throws DAOException {
		return this.getById(id, false);
	}

	
	public ContactGroup getById(Integer id, boolean getContacts) throws DAOException {
		try {
			Object contactGroupO = super.getHibernateTemplate().get(ContactGroup.class, id);
			if (contactGroupO != null && contactGroupO instanceof ContactGroup) {
				if (getContacts) {
					// call the size method for loading the contacts
					((ContactGroup) contactGroupO).getContacts().size();
				}
				return (ContactGroup) contactGroupO;
			}
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		throw new DAOException("Impossible to get the contact group. getById(" + id + "). ");
	}

	
	public ContactGroup addContactGroup(String groupName, Set<Contact> contacts)
			throws DAOException {
		return this.addContactGroup(POJOFactory.instance.newContactGroup(groupName, contacts));
	}

	
	public ContactGroup addContactGroup(ContactGroup group) throws DAOException {
		try {
			Serializable newId = super.getHibernateTemplate().save(group);
			if (newId instanceof Integer)
				group.setGroupId((Integer) newId);
			else // all ids are Integer in our database
				throw new HibernateException("Impossible to get the id of the new ContactGroup.");
			return group;
		} catch (DataAccessException e) {
			e.printStackTrace();
			throw new DAOException("Impossible to create the ContactGroup. " + e.getMessage());
		}
	}
	
	public ContactGroup updateContactGroup(int id, long version, String groupName,
			Set<Contact> contacts) throws DAOException, VersionException {
		ContactGroup group = POJOFactory.instance.newContactGroup(groupName, contacts);
		group.setGroupId(id);
		group.setVersion(version);
		return this.updateContactGroup(group);
	}

	
	public ContactGroup updateContactGroup(ContactGroup group) throws DAOException, VersionException {
		// versionning verification
		long version = super.getVersionDB(ContactGroup.class, group.getGroupId());
		if (version != group.getVersion())
			throw new VersionException();
		
		try {
			// update the version before save the adress modification
			group.setVersion(group.getVersion() + 1);
			super.getHibernateTemplate().update(group);
			return group;
		} catch (DataAccessException e) {
			e.printStackTrace();
			throw new DAOException("Impossible to update the contact group. " + e.getMessage());
		}
	}

	
	public boolean deleteContactGroup(int id) throws DAOException {
		ContactGroup group = this.getById(id);
		try {
			super.getHibernateTemplate().delete(group);
			return true;
		} catch (DataAccessException e) {
			e.printStackTrace();
			throw new DAOException("Impossible to delete the contact group. " + e.getMessage());
		}
	}
}
